/*===============================================
*   文件名称：tcp_server.c
*   创 建 者: 麦穗飘飘
*   创建日期：2024年09月26日   16:53:46
*   描    述：
================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/time.h>

#define MAX_CLIENTS 10
#define BUFFER_SIZE 1024

int main() {
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int addrlen = sizeof(address);
    int max_fd = 0;
    fd_set readfds;
    struct timeval timeout;

    char buffer[BUFFER_SIZE] = {0};
    int client_sockets[MAX_CLIENTS];

    // 创建套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 设置地址结构
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(6000);

    // 绑定套接字
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(server_fd, 3) < 0) {
        perror("listen failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    // 初始化客户端套接字数组
    for (int i = 0; i < MAX_CLIENTS; i++) {
        client_sockets[i] = 0;
    }

    // 初始化最大文件描述符
    max_fd = server_fd;

    while (1) {
        FD_ZERO(&readfds);
        FD_SET(server_fd, &readfds);

        // 将所有活动的客户端套接字添加到读集
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (client_sockets[i] > 0) {
                FD_SET(client_sockets[i], &readfds);
                max_fd = (max_fd > client_sockets[i]) ? max_fd : client_sockets[i];
            }
        }

        // 设置超时时间
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;

        // 执行 select
        int ret = select(max_fd + 1, &readfds, NULL, NULL, &timeout);
        if (ret < 0) {
            perror("select error");
            continue;
        }

        // 检查是否有新的连接请求
        if (FD_ISSET(server_fd, &readfds)) {
            if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {
                perror("accept failed");
                continue;
            }
            printf("New connection, socket fd is %d\n", new_socket);
            for (int i = 0; i < MAX_CLIENTS; i++) {
                if (client_sockets[i] == 0) {
                    client_sockets[i] = new_socket;
                    break;
                }
            }
        }

        // 处理客户端数据
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (client_sockets[i] > 0 && FD_ISSET(client_sockets[i], &readfds)) {
                valread = read(client_sockets[i], buffer, BUFFER_SIZE);
                if (valread <= 0) {
                    close(client_sockets[i]);
                    client_sockets[i] = 0;
                    continue;
                }
                printf("Received from client: %s\n", buffer);
                // 可以在这里处理数据或发送响应
            }
        }
    }

    // 关闭所有套接字
    close(server_fd);

    return 0;
} 
